home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_078 / mandelvroom / mand.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  18KB  |  727 lines

  1. /***************************************************************************
  2.  *
  3.  *                       MandelVroom Generator
  4.  *
  5.  *                         Kevin L. Clague
  6.  *
  7.  *                        Copyright (C) 1987
  8.  *
  9.  **************************************************************************/
  10.  
  11. #include "mand.h"
  12.  
  13. #define PICTWINDXSIZE 100
  14. #define PICTWINDYSIZE 100
  15.  
  16. #define PICTXSIZE  (PICTWINDXSIZE - LEFTMARG - RIGHTMARG)
  17. #define PICTYSIZE  (PICTWINDYSIZE - TOPMARG - BOTMARG)
  18.  
  19. #define DEFAULTLEFT  -2.0
  20. #define DEFAULTRIGHT  2.0
  21. #define DEFAULTTOP   -2.0
  22. #define DEFAULTBOT    2.0
  23.  
  24. extern struct Screen   *screen;
  25. extern struct RastPort *rp;
  26.  
  27. extern SHORT *CountBase;
  28. extern LONG NavTop, NavBot, NavLeft, NavRight;
  29.  
  30. extern SHORT Zoom;
  31.  
  32. extern struct Menu Menu, GenMenu;
  33.  
  34. extern SHORT *ContourBase;
  35. extern UBYTE *ColorBase, MandType;
  36.  
  37. struct Window *MandWind = (struct Window *) NULL;
  38.  
  39. struct NewWindow NewMand = {
  40.    0,1,                      /* start position           */
  41.    80,80,                    /* width, height            */
  42.    (UBYTE) 0, (UBYTE) 1,     /* detail pen, block pen    */
  43.                              /* IDCMP flags */
  44.    MENUPICK | GADGETDOWN | GADGETUP | MOUSEBUTTONS,
  45.    WINDOWDEPTH | WINDOWSIZING | ACTIVATE | REPORTMOUSE, /* MandWind flags */
  46.    (struct Gadget *) NULL,   /* first gadget             */
  47.    (struct Image *) NULL,    /* user checkmark           */
  48.    (UBYTE *) "Picture",      /* MandWind title             */
  49.    (struct Screen *) NULL,   /* pointer to screen        */
  50.    (struct BitMap *) NULL,   /* pointer to superbitmap   */
  51.    80,80,320,200,            /* sizing                   */
  52.    CUSTOMSCREEN              /* type of screen           */
  53.    };
  54.  
  55. float StartX = DEFAULTLEFT;
  56. float StartY = DEFAULTTOP;
  57. float EndX   = DEFAULTRIGHT;
  58. float EndY   = DEFAULTBOT;
  59.  
  60. float GapY = ( DEFAULTBOT - DEFAULTTOP ) / PICTXSIZE;
  61. float GapX = 0.88 * ( DEFAULTBOT - DEFAULTTOP ) / PICTYSIZE;
  62.  
  63. SHORT MaxCount = 1023;
  64.  
  65. SHORT CountX = PICTXSIZE;
  66. SHORT CountY = PICTYSIZE;
  67.  
  68. ULONG CalcTime;
  69.  
  70. /*
  71.  * Generate It
  72.  */
  73. GenerateIt()
  74. {
  75.  ClosePalWind();
  76.  CloseContWind();
  77.  
  78.  ClearMenuStrip(MandWind);
  79.  SetMenuStrip(MandWind, &GenMenu);
  80.  
  81.  switch ( MandType ) {
  82.    case 0:
  83.         IntMandelbrot();
  84.         break;
  85.    case 1:
  86.         Mandelbrot();
  87.         break;
  88.  }
  89.  
  90.  ClearMenuStrip(MandWind);
  91.  SetMenuStrip(MandWind, &Menu);
  92. }
  93.  
  94. /*
  95.  * Fast Floating Point Mandelbrot Generator
  96.  */
  97. Mandelbrot()
  98. {
  99.   int i, j, k, l;
  100.   int TraceSize = 32;
  101.  
  102.   register float cura, curb, cura2, curb2;
  103.  
  104.   float curx, cury, napx, napy;
  105.   float olda[64], oldb[64];
  106.   float *RealTrace,*ImagTrace;
  107.  
  108.   SHORT *CountPtr;
  109.  
  110.   UBYTE  ColorXlate[1030];
  111.  
  112. #asm
  113. olda      equ -548
  114. oldb      equ -292
  115. TraceSize equ -20
  116. l         equ -16
  117. k         equ -12
  118. curx      equ -24
  119. cury      equ -28
  120. #endasm
  121.  
  122.   /* Map contours into color translate table */
  123.   for (i = 0,j = 1029; i < NUMCONTS; i++)
  124.     for (; j >= ContourBase[i] && j; )
  125.       ColorXlate[j--] = ColorBase[i];
  126.  
  127.   while (j >= 0) ColorXlate[j--] = 0;
  128.  
  129.   /* free up old counts memory, get new picture size, get new counts memory
  130.    */
  131.   GetCountsMemory();
  132.  
  133.   /* clear the picture area */
  134.  
  135.   SetAPen(MandWind->RPort, 0);
  136.  
  137.   RectFill(MandWind->RPort, LEFTMARG, TOPMARG,
  138.                             MandWind->Width - 12,  MandWind->Height - 2);
  139.   CountPtr = CountBase;
  140.  
  141.   /* calculate new picture's coordinates from zoom box */
  142.   ZoomIn();
  143.  
  144.   /* start in the upper left hand corner */
  145.   cury = StartY;
  146.  
  147.   /*
  148.    * for each pixel, calculate mandelbrot
  149.    */
  150.   for (i = 0; i < CountY; i++) {
  151.     curx = StartX;
  152.     for (j = 0; j < CountX; j++) {
  153.       cura = curb = cura2 = curb2 = 0;
  154.       for (k = 0; k < MaxCount; k += TraceSize) {
  155.  
  156. #ifdef SLOW
  157.         RealTrace = olda;
  158.         ImagTrace = oldb;
  159.         for (l = 0; l < TraceSize; l++) {
  160.           *(RealTrace++) = cura;
  161.           *(ImagTrace++) = curb;
  162.  
  163.           curb *= cura;
  164.           curb += curb + cury;
  165.  
  166.           cura = cura2 - curb2 + curx;
  167.  
  168.           cura2 = cura * cura;
  169.           curb2 = curb * curb;
  170.           if (cura2+curb2 > 4.0)
  171.             goto out;
  172.         }
  173.         RealTrace = olda;
  174.         ImagTrace = oldb;
  175.         for (l = 0; l < TraceSize; l++)
  176.           if (cura == *(RealTrace++) && curb == *(ImagTrace++)) {
  177.             k += MaxCount;
  178.             goto out;
  179.           }
  180. #else
  181. #asm
  182.        public  _LVOSPMul
  183.        public  _LVOSPAdd
  184.        public  _LVOSPSub
  185.        public  _LVOSPCmp
  186.        public  _MathBase
  187.        move.l  _MathBase,a6
  188.        lea.l    olda(a5),a0        ;   RTrace = olda
  189.        lea.l    oldb(a5),a1        ;   ITrace = oldb
  190.        clr.l    l(a5)              ;for (l = TraceSize; l--; ) {
  191. lloop  move.l   d4,(a0)+           ;   *(RTrace++) = cura
  192.        move.l   d5,(a1)+           ;   *(ITrace++) = curb
  193.        move.l   d4,d0              ;   curb *= cura
  194.        move.l   d5,d1
  195.        jsr     _LVOSPMul(a6)
  196.        move.l   d0,d1              ;   curb += curb
  197.        jsr     _LVOSPAdd(a6)
  198.        move.l   cury(a5),d1        ;   curb += cury
  199.        jsr     _LVOSPAdd(a6)
  200.        move.l   d0,d5
  201.        move.l   d6,d0              ;   cura = cura2-curb2+curx
  202.        move.l   d7,d1
  203.        jsr     _LVOSPSub(a6)
  204.        move.l   curx(a5),d1
  205.        jsr     _LVOSPAdd(a6)
  206.        move.l   d0,d4
  207. ;
  208.        move.l   d0,d1              ;   cura2 = cura*cura
  209.        jsr     _LVOSPMul(a6)
  210.        move.l   d0,d6
  211.        move.l   d5,d0              ;   curb2 = curb*curb
  212.        move.l   d5,d1
  213.        jsr     _LVOSPMul(a6)
  214.        move.l   d0,d7
  215.        move.l   d6,d1              ;   if (cura2+curb2 > 4.0) goto out:
  216.        jsr     _LVOSPAdd(a6)
  217.        move.l   #$80000043,d1
  218.        jsr     _LVOSPCmp(a6)
  219.        bgt      out
  220.        add.l    #1,l(a5)
  221.        move.l   l(a5),d0
  222.        cmp.l    TraceSize(a5),d0
  223.        blt      lloop
  224. ;
  225.        lea      olda(a5),a0        ;   RTrace = olda
  226.        lea      oldb(a5),a1        ;   ITrace = oldb
  227.        clr.l    l(a5)              ;   for (l = TraceSize; l--; )
  228. lloop1
  229.        cmp.l    (a0)+,d4
  230.        bne      skipit
  231.        cmp.l    (a1)+,d5
  232.        bne      nextl
  233.        move.w  _MaxCount,d0
  234.        ext.l    d0
  235.        move.l   d0,k(a5)
  236.        move.l   #0,l(a5)
  237.        bra      out
  238. skipit
  239.        add.l    #4,a1
  240. nextl
  241.        add.l    #1,l(a5)
  242.        move.l   l(a5),d0
  243.        cmp.l    TraceSize(a5),d0
  244.        blt      lloop1
  245. #endasm
  246. #endif
  247.       }
  248.       k = 0;
  249.       l = MaxCount;
  250. out:
  251. #asm
  252. out
  253. #endasm
  254.       SetAPen(rp, ColorXlate[ k + l ]);
  255.  
  256.       WritePixel(rp, j + LEFTMARG,i + TOPMARG);
  257.  
  258.       if (CountPtr)
  259.         *(CountPtr++) = k + l;
  260.  
  261.       curx += GapX;
  262.       if ( CheckForStop() ) {
  263.  
  264.         DisplayBeep(screen);
  265.         return(0);
  266.       }
  267.     }
  268.     cury += GapY;
  269.   }
  270.  
  271.   DisplayBeep(screen);
  272. } /* Mandelbrot */
  273.  
  274. /*
  275.  * 32 bit fixed point generator
  276.  */
  277. IntMandelbrot()
  278. {
  279.   LONG i, j, k;
  280.  
  281.   LONG curx, cury, gapx, gapy;
  282.   register LONG cura, curb, cura2, curb2;
  283.  
  284.   float gap;
  285.  
  286.   SHORT *CountPtr;
  287.   LONG  OldA[32],OldB[32];
  288.  
  289.   UBYTE MandFlag;
  290.  
  291.   UBYTE  ColorXlate[1030];
  292.  
  293.   UBYTE OldPen, NewPen;
  294.  
  295.   LONG xl,yl;
  296.  
  297.   OldPen = 0xff;
  298.  
  299. #define BITS2SHIFT 27
  300.  
  301.   /* Map contours into color translate table */
  302.   for (i = 0,j = 1029; i < NUMCONTS; i++)
  303.     for (; j >= ContourBase[i] && j; )
  304.       ColorXlate[j--] = ColorBase[i];
  305.  
  306.   while (j >= 0) ColorXlate[j--] = 0;
  307.  
  308.   /* free up old counts memory, get new picture size, get new counts memory
  309.    */
  310.  
  311.   GetCountsMemory();
  312.  
  313.   /* clear the picture area */
  314.  
  315.   SetAPen(MandWind->RPort, 0);
  316.  
  317.   RectFill(MandWind->RPort, LEFTMARG, TOPMARG,
  318.                             MandWind->Width - 12,  MandWind->Height - 2);
  319.   CountPtr = CountBase;
  320.  
  321.   /* calculate new picture's coordinates from zoom box */
  322.  
  323.   ZoomIn();
  324.  
  325.   /* figure out horizontal and verticle distances between points in plane.
  326.    * convert them to fixed point format                                    */
  327.  
  328.   gapy = (int) (GapY*((float)(1<<BITS2SHIFT)));
  329.   gapx = (int) (GapX*((float)(1<<BITS2SHIFT)));
  330.  
  331.   /*
  332.    * for each point in the image, calculate Mandelbrot
  333.    */
  334.   cury = (int)(StartY*((float)(1<<BITS2SHIFT)));
  335.  
  336.   xl = LEFTMARG + CountX;
  337.   yl = TOPMARG + CountY;
  338.  
  339.   for (i = TOPMARG; i < yl; i++) {
  340.     curx = (int)(StartX*((float)(1<<BITS2SHIFT)));
  341.     MandFlag = 0;
  342.     for (j = LEFTMARG; j < xl; j++) {
  343.       /*
  344.        * if the last pixel was mandelbrot, then use trace table
  345.        */
  346.       if (MandFlag) {
  347. #asm
  348. Bits2Shift equ 5
  349. ;
  350. ;  d1 - a2
  351. ;  d2 - b2
  352. ;  d4 - a
  353. ;  d5 - b
  354. ;  d6 - BITS2SHIFT
  355. ;  d7 - k
  356. ;
  357. ;  a0 - OldA
  358. ;  a1 - OldB
  359. ;
  360. ;  cura = curb = curc = curd = 0;
  361. OldA equ -292
  362. OldB equ -164
  363. Trace equ 15
  364.    moveq    #0,d1
  365.    moveq    #0,d2
  366.    moveq    #0,d4
  367.    moveq    #0,d5
  368.    move.w   d5,k(a5)
  369.    move.l   #Bits2Shift,d6
  370. AddrLoop
  371.    move.w   #Trace,d7
  372.    lea      OldA(a5),a0
  373. ;  lea      OldB(a5),a1
  374. KLoop
  375.    move.l   d0,(a0)+   ; save todays version of Magnitude
  376. ;  move.l   d5,(a1)+   ; save todays version of B
  377. ;
  378. ;  cura = cura2 - curb2 + curx;
  379.    exg      d1,d4      ; exchange cura and cura2
  380.    sub.l    d2,d4      ; subtract curb
  381.    add.l   -16(a5),d4  ; add curx
  382. ;
  383. ;  curb = cura * curb >> 12;
  384.    move.l   d1,d2      ; get copy of op1 sign bit
  385.    bpl      pos1       ; get absolute value of op1
  386.    neg.l    d1
  387. pos1
  388.    eor.l    d5,d2      ; calculate result sign
  389.    tst.l    d5         ; get absolute value of op2
  390.    bpl      pos2
  391.    neg.l    d5
  392. pos2
  393.    move.l   d1,d0      ; get a copy of op1
  394.    swap     d0         ; get high half of op1
  395.    move.w   d0,d2      ; save a copy of high half
  396.    mulu     d5,d0      ; multiply op2 low by op1 high
  397.    clr.w    d0         ;  clear least significant part
  398.    swap     d0         ;  put it in it's place
  399.    swap     d5         ; get high half of op2
  400.    mulu     d5,d1      ; multiply op2 high with op1 low
  401.    clr.w    d1         ;  clear least significant part
  402.    swap     d1         ;  put it in its place
  403.    mulu     d2,d5      ; multiply op2 high by op1 high
  404.    add.l    d0,d5      ; add partial results
  405.    add.l    d1,d5      ; add partial results
  406.    tst.l    d2         ; is the result negative?
  407.    bpl      pos3
  408.    neg.l    d5         ; yes, better negate it.
  409. pos3
  410.    asl.l    d6,d5      ; now, rescale it.
  411. ;
  412. ;  curb += curb + cury;
  413.    add.l    d5,d5      ; double it and add cury
  414.    add.l   -20(a5),d5
  415. ;
  416. ;  cura2 = cura * cura;
  417.    move.l   d4,d0      ; get absolute value of a in d0
  418.    bpl      posa
  419.    neg.l    d0
  420. posa
  421.    move.l   d0,d1      ; copy absolute value into d1
  422.    swap     d1         ; get high part in d1
  423.    mulu     d1,d0      ; multiply high and low destroying low
  424.    clr.w    d0         ; clear the least significant part
  425.    swap     d0         ; put most sig. part in low half
  426.    mulu     d1,d1      ; multiply high and high destroing high
  427.    add.l    d0,d1      ; add in lower half twice
  428.    add.l    d0,d1
  429.    asl.l    d6,d1      ; get radix point back in correct place
  430.    bvs      bailout
  431. ;
  432. ;  curb2 = curb * curb;
  433.    move.l   d5,d0      ; get absolute value of a in d0
  434.    bpl      posb
  435.    neg.l    d0
  436. posb
  437.    move.l   d0,d2      ; copy absolute value into d2
  438.    swap     d2         ; get high part in d2
  439.    mulu     d2,d0      ; multiply high and low destroying low
  440.    clr.w    d0         ; clear the least significant part
  441.    swap     d0         ; put most sig. part in low half
  442.    mulu     d2,d2      ; multiply high and high destroing high
  443.    add.l    d0,d2      ; add in lower half twice
  444.    add.l    d0,d2
  445.    asl.l    d6,d2      ; get radix point back in correct place
  446.    bvs      bailout
  447. ;
  448.    move.l   d1,d0      ; if (cura2 + curb2 >= 4) goto bailout;
  449.    add.l    d2,d0
  450.    bvs      bailout
  451.    cmp.l    #536870912,d0
  452.    bge      bailout
  453.    dbra     d7,KLoop   ; keep going
  454. ;
  455.    move.w   #Trace,d7
  456.    lea      OldA(a5),a0
  457. ;  lea      OldB(a5),a1
  458. SLoop
  459.    cmp.l    (a0)+,d4   ; check A
  460. ;  bne      NotIt
  461. ;  cmp.l    (a1),d5    ; check B
  462.    beq      GotIt
  463. NotIt
  464.    add      #2,a1
  465.    dbra     d7,SLoop   ; check next one
  466.    add.w    #Trace,k(a5)  ; drop the iteration count
  467.    cmp.w    #1023-Trace,k(a5)
  468.    blt      AddrLoop
  469. ;
  470. GotIt
  471.    move.w   #1023,d0
  472.    bra      Adjusted
  473. bailout
  474.    move.b   #0,-293(a5) ; clear MandFlag here
  475.    move.w   #Trace,d0
  476.    sub.w    d7,d0
  477.    add.w    k(a5),d0
  478. Adjusted
  479.    ext.l    d0
  480.    move.l   d0,-12(a5)
  481. #endasm
  482.    ;} else {
  483.    /*  This code does mandelbrot without any trace lookup.
  484.     *  It is the fastest generator in the house.
  485.     */
  486. #asm
  487. ;
  488. ;  d1 - a2
  489. ;  d2 - b2
  490. ;  d4 - a
  491. ;  d5 - b
  492. ;  d6 - BITS2SHIFT
  493. ;  d7 - k
  494. ;
  495. ;  cura = curb = curc = curd = 0;
  496.    moveq    #0,d1
  497.    moveq    #0,d2
  498.    moveq    #0,d4
  499.    moveq    #0,d5
  500.    move.l   #Bits2Shift,d6
  501.    move.w   #1023,d7
  502. FKLoop
  503. ;
  504. ;  cura = cura2 - curb2 + curx;
  505.    exg      d1,d4      ; exchange cura and cura2
  506.    sub.l    d2,d4      ; subtract curb
  507.    add.l   -16(a5),d4  ; add curx
  508. ;
  509. ;  curb = cura * curb >> 12;
  510.    move.l   d1,d2      ; get copy of op1 sign bit
  511.    bpl      Fpos1       ; get absolute value of op1
  512.    neg.l    d1
  513. Fpos1
  514.    eor.l    d5,d2      ; calculate result sign
  515.    tst.l    d5         ; get absolute value of op2
  516.    bpl      Fpos2
  517.    neg.l    d5
  518. Fpos2
  519.    move.l   d1,d0      ; get a copy of op1
  520.    swap     d0         ; get high half of op1
  521.    move.w   d0,d2      ; save a copy of high half
  522.    mulu     d5,d0      ; multiply op2 low by op1 high
  523.    clr.w    d0         ;  clear least significant part
  524.    swap     d0         ;  put it in it's place
  525.    swap     d5         ; get high half of op2
  526.    mulu     d5,d1      ; multiply op2 high with op1 low
  527.    clr.w    d1         ;  clear least significant part
  528.    swap     d1         ;  put it in its place
  529.    mulu     d2,d5      ; multiply op2 high by op1 high
  530.    add.l    d0,d5      ; add partial results
  531.    add.l    d1,d5      ; add partial results
  532.    tst.l    d2         ; is the result negative?
  533.    bpl      Fpos3
  534.    neg.l    d5         ; yes, better negate it.
  535. Fpos3
  536.    asl.l    d6,d5      ; now, rescale it.
  537. ;
  538. ;  curb += curb + cury;
  539.    add.l    d5,d5      ; double it and add cury
  540.    add.l   -20(a5),d5
  541. ;
  542. ;  cura2 = cura * cura;
  543.    move.l   d4,d0      ; get absolute value of a in d0
  544.    bpl      Fposa
  545.    neg.l    d0
  546. Fposa
  547.    move.l   d0,d1      ; copy absolute value into d1
  548.    swap     d1         ; get high part in d1
  549.    mulu     d1,d0      ; multiply high and low destroying low
  550.    clr.w    d0         ; clear the least significant part
  551.    swap     d0         ; put most sig. part in low half
  552.    mulu     d1,d1      ; multiply high and high destroing high
  553.    add.l    d0,d1      ; add in lower half twice
  554.    add.l    d0,d1
  555.    asl.l    d6,d1      ; get radix point back in correct place
  556.    bvs      Fbailout
  557. ;
  558. ;  curb2 = curb * curb;
  559.    move.l   d5,d0      ; get absolute value of a in d0
  560.    bpl      Fposb
  561.    neg.l    d0
  562. Fposb
  563.    move.l   d0,d2      ; copy absolute value into d2
  564.    swap     d2         ; get high part in d2
  565.    mulu     d2,d0      ; multiply high and low destroying low
  566.    clr.w    d0         ; clear the least significant part
  567.    swap     d0         ; put most sig. part in low half
  568.    mulu     d2,d2      ; multiply high and high destroing high
  569.    add.l    d0,d2      ; add in lower half twice
  570.    add.l    d0,d2
  571.    asl.l    d6,d2      ; get radix point back in correct place
  572.    bvs      Fbailout
  573. ;
  574.    move.l   d1,d0      ; if (cura2 + curb2 >= 4) goto bailout;
  575.    add.l    d2,d0
  576.    bvs      Fbailout
  577.    cmp.l    #536870912,d0
  578.    bge      Fbailout
  579.    dbra     d7,FKLoop
  580.    move.b   #1,-293(a5) ; set MandFlag here
  581. Fbailout
  582.    move.w   #1023,d0
  583.    sub.w    d7,d0
  584.    move.w   d0,d7
  585.    ext.l    d7
  586.    move.l   d7,-12(a5)
  587. #endasm
  588.       }
  589.       NewPen = ColorXlate[k];
  590.  
  591.  
  592.       if (NewPen != OldPen) {
  593.         SetAPen(rp,NewPen);
  594.         OldPen = NewPen;
  595.       }
  596.  
  597.       if (NewPen)
  598.         WritePixel(rp, j, i);
  599.  
  600.       if (CountPtr)
  601.         *(CountPtr++) = k;
  602.  
  603.       curx += gapx;
  604.       if ( CheckForStop() ) {
  605.         /* Clean up here */
  606.         DisplayBeep(screen);
  607.         return(0);
  608.       }
  609.     }
  610.     cury += gapy;
  611.   }
  612.   DisplayBeep(screen);
  613. } /* Mandelbrot */
  614.  
  615. /*
  616.  * Free up old memory and get memory for new picture
  617.  */
  618. GetCountsMemory()
  619. {
  620.   /* free up old pictures iteration count pile */
  621.  
  622.   if (CountBase) {
  623.     FreeMem(CountBase,CountX*CountY*sizeof(SHORT));
  624.     CountBase = (SHORT *) NULL;
  625.   }
  626.  
  627.   /* figure out new picture size */
  628.  
  629.   CountX = MandWind->Width-(LEFTMARG+RIGHTMARG);
  630.   CountY = MandWind->Height-(TOPMARG+BOTMARG);
  631.  
  632.   /* Allocate memory for new picture */
  633.  
  634.   CountBase = (SHORT *) AllocMem(CountX*CountY*sizeof(SHORT),MEMF_CLEAR);
  635.   if (CountBase == (SHORT *) NULL) {
  636.     DispErrMsg("Can't save counts. Out of RAM!!",0);
  637.     return(1);
  638.   }
  639.   return(0);
  640. }
  641.  
  642. /*
  643.  * ZoomIn
  644.  */
  645. ZoomIn()
  646. {
  647.   if (Zoom) {
  648.     EndY   = StartY + GapY * (float)(NavBot-TOPMARG);
  649.     EndX   = StartX + GapX * (float)(NavRight-LEFTMARG);
  650.     StartY = StartY + GapY * (float)(NavTop-TOPMARG);
  651.     StartX = StartX + GapX * (float)(NavLeft-LEFTMARG);
  652.  
  653.     Zoom = 0;
  654.   }
  655.  
  656.   CalculateGaps();
  657. } /* ZoomIn */
  658.  
  659. /*
  660.  * Calculate Gaps
  661.  */
  662. CalculateGaps()
  663. {
  664.   GapY = (EndY-StartY)/(float)CountY;
  665.  
  666.   if (screen->ViewPort.Modes & HIRES)
  667.     if (screen->ViewPort.Modes & INTERLACE)
  668.       GapX = GapY*0.88;
  669.     else
  670.       GapX = GapY*0.44;
  671.   else
  672.     if (screen->ViewPort.Modes & INTERLACE)
  673.       GapX = GapY*1.76;
  674.     else
  675.       GapX = GapY*0.88;
  676. }
  677.  
  678. /*
  679.  * Check For Stop
  680.  */
  681. CheckForStop()
  682. {
  683.   struct IntuiMessage *message;
  684.   struct Gadget *gadget;
  685.   ULONG  class;
  686.   USHORT code;
  687.  
  688.   message = (struct IntuiMessage *) GetMsg(MandWind->UserPort);
  689.  
  690.   if (message) {
  691.     class  = message->Class;
  692.     code   = message->Code;
  693.     ReplyMsg(message);
  694.  
  695.     if (class == MENUPICK && code != MENUNULL) {
  696.       ClearMenuStrip(MandWind);
  697.       return(1);
  698.     }
  699.   }
  700.   return(0);
  701. } /* Check for stop */
  702.  
  703. /*
  704.  * Open the Mandelbrot window
  705.  */
  706. OpenMandWind()
  707. {
  708.   extern struct Window *OpenMyWind();
  709.  
  710.   if (MandWind == (struct Window *) NULL) {
  711.     MandWind = OpenMyWind(&NewMand, screen, NULL, 109, 78, 320, 200);
  712.     SetMenuStrip(MandWind, &Menu);
  713.     ForceNormPointer();
  714.   }
  715. } /* OpenMandWind */
  716.  
  717. /*
  718.  * Close the Mandelbrot Window
  719.  */
  720. CloseMandWind()
  721. {
  722.   if (MandWind != (struct Window *) NULL) {
  723.     CloseMyWind(MandWind, NewMand.FirstGadget);
  724.     MandWind = (struct Window *) NULL;
  725.   }
  726. } /* CloseMandWind */
  727.